<?php

/**
 * 维尼供供应链-花之冠技术对接群
 * @author chenshubo
 */
namespace App\Service\VendorClient\ShopWeiNi;
use App\Service\BaseService;
use App\Service\Code\Normal;
use Service\AppService\IdService;
use App\Service\TaskServer\TaskWorker;
use App\Model\PssModel\ServiceConfig;

class ShopWeiNiApiClient extends BaseService
{
    protected $clientConfig;

    public function __construct($apiBody = [])
    {
        $this->clientConfig = $apiBody;
    }

    /**
     * 创建订单
     */
    public function createOrder( $params = [] )
    {
        $orderInfo      = $params['supplierOrder'];
        $orderItem      = $params['orderGoods'];
        $order          = $params['order'];
        $binfo          = $params['binfo'];
        //支付流水号
        $pay_sn         = $order['paySerial'] ?? $orderInfo['pay_sn'];
        //运费
        $deliver_money  = $orderInfo['deliver_money']; //因为运费已经加到商品金额中了
        //下单支付的时候支付信息
        $apply_extends  = @json_decode($orderInfo['apply_extends'],true);
        //支付时间
        $pay_time       = date('Y-m-d H:i:s',$orderInfo['pay_time']);
        //支付流水号
        $pay_sn         = $order['paySerial'] ?? $orderInfo['pay_sn'];
        $order_sn       = $orderInfo['supplier_dsn'];
        
        //判断商品类型
        $currentGoods   = current($orderItem);
        $goods_type     = $currentGoods['goods_type'];
        
        //组装商品数据列表
        $goodsList          = [];
        $goodsTotalMoney    = 0;
        $way_tax_fee        = 0;
        foreach ($orderItem as $key =>  & $item )
        {
            $rate               = (string)$item['tax_rate'];
            $tax_rate           = bcadd('1', $rate,4);
            $price              = $item['price'];
            $spec_num           = $item['spec_num'];
            $quantity           = $item['quantity'];
            $supplier_skucode   = $item['supplier_skucode'];
            $goods_type         = $item['goods_type'];
            
            //包邮
            if( $key == 0 ) {
                $singleDeliveryMoney = bcdiv((string)$deliver_money,(string)$quantity,3);
                $singleDeliveryMoney = bcmul((string)$singleDeliveryMoney,(string)100,1);
                $singleDeliveryMoney = bcdiv((string)ceil($singleDeliveryMoney), (string)100,2);
                $price               = bcadd((string)$price, (string)$singleDeliveryMoney,2);
            }

            //保税区订单
            if( $goods_type == 1 ) 
            {
                //不含税价格
                $singleGoodsPrice       = bcdiv((string)$price, (string)$tax_rate,2);
//                $singleGoodsPrice       = bcmul((string)$singleGoodsPrice,(string)100,1);
//                $singleGoodsPrice       = bcdiv((string)ceil($singleGoodsPrice), (string)100,2);

                //商品总价
                $goodsTotalPrice        = bcmul((string)$singleGoodsPrice,(string)$quantity,2);
                
                //含税商品总价
                $goodsTotalHasTaxPrice  = bcmul((string)$price,(string)$quantity,2);
                
                //总税金
                $taxAll                 = bcsub((string)$goodsTotalHasTaxPrice, (string)$goodsTotalPrice,2);
            }
            else 
            {
                $singleGoodsPrice       = $price;
                $goodsTotalPrice        = bcmul((string)$price,(string)$quantity,2);
                $taxAll                 = 0.00;
            }
            
            $goodsInfo = [
                "BuyQuantity"   => $quantity,
                "SkuNo"         => $supplier_skucode,
                "Tax"           => $taxAll,
                "BuyPrice"      => (string)$singleGoodsPrice,
            ];
            $goodsList[] = $goodsInfo;
            
            //单商品总金额
            $goodsTotalMoney    = bcadd((string)$goodsTotalMoney,(string)$goodsTotalPrice,2);
            //保税品单商品总税金
            $way_tax_fee        = bcadd((string)$way_tax_fee,(string)$taxAll,2);
        }

        //订单总价（商品保税价格 + 运费）
        $totalMoney             = bcadd((string)$goodsTotalMoney,(string)$way_tax_fee,2);

        //订单优惠金额
        $real_total_money       = $orderInfo['real_total_money'];
        $discount_money         = bcsub((string)$totalMoney,(string)$real_total_money,2);
        
        //判断支付方式是否存在
        $payCommanyCode = $apply_extends['payCommanyCode']??'';
        $PayCompanyCode = $order['payCommanyCode'] ? $order['payCommanyCode'] : $payCommanyCode ;
        $pay_value = ServiceConfig::instance()->getConfigByEventsValue('shopweini', ServiceConfig::TYPE_PAY, $PayCompanyCode);
        if( empty($pay_value) ) {
            return Normal::returnCode(Normal::FAIL,"支付公司编码：【{$PayCompanyCode}】未映射，请联系管理员处理");
        }

        //创建订单数据
        $data = [
            "OrderTime"                 => date("YmdHis",$orderInfo['cd']),
            "OrderItems"                => $goodsList,
            "PostalPrice"               => 0.00,
            "GoodsPrice"                => $goodsTotalMoney,
            "OrderPrice"                => $real_total_money,
            "OrderNo"                   => $order_sn,
            "Tax"                       => $way_tax_fee,
            "PayType"                   => $pay_value,
            "Nick"                      => $orderInfo['buyer_realname'],
            "PayNo"                     => $pay_sn,
            "PayerName"                 => $orderInfo['buyer_realname'],
            "IdCard"                    => $orderInfo['buyer_idcard'],
            "Province"                  => $orderInfo['province'],
            "City"                      => $orderInfo['city'],
            "District"                  => $orderInfo['district'],
            "DetailedAddres"            => $orderInfo['receive_address'],
            "Remark"                    => $orderInfo['order_remark'],
            "ConsigneeName"             => $orderInfo['receive_name'],
            "ConsigneeNumber"           => $orderInfo['recveive_phone'],
            "Favourable"                => $discount_money,
            "DeliveryType"              => $currentGoods['supplier_goods_type'],
            "IsAllowSplit"              => 0,
            "EbpCode"                   => $order['enterpriseNum']??$apply_extends['enterpriseNum']??'',
            "EbpName"                   => $order['enterpriseName']??$apply_extends['enterpriseName']??'',
        ];
        $requestParam = [
            'method'    => 'AddOrderAsync',
            'data'      => $data,
        ];
        return $this->execute($requestParam);
    }

    /**
     * 取消订单
     * @param array $param
     */
    public function orderCancel( $param = [] )
    {
        if( empty($param['supplierOrder']) ) {
            return Normal::returnCode(Normal::FAIL,"except param supplierOrder");
        }
        //创建订单数据
        $data = [
            "OrderNo"   => $param['supplierOrder']['thirdpart_order_sn'],
            "Reason"    => "取消订单，不要了",
        ];
        $requestParam = [
            'method'    => 'OrderCancel',
            'data'      => $data,
        ];
        return $this->execute($requestParam);
    }

    /**
     * 获取商品列表
     */
    public function queryGoodsList($param=[])
    {
        //创建订单数据
        $data = [
            'PageNo'    => $param['page'] ?? 1,
            'PageNum'   => $param['limit'] ?? 10,
            "Status"    => $param['status'] ?? '上架',
        ];
        if (!empty($param['delivery_code'])){
            $data['DeliveryCode']=$param['delivery_code'];
        }
        if (!empty($param['sale_type'])){
            $data['SaleType']=$param['sale_type'];
        }
        if (!empty($param['sale_type'])){
            $data['SaleType']=$param['sale_type'];
        }

        $requestParam = [
            'method'    => 'SkuListSynchro',
            'data'      => $data,
        ];
        $responseParam=$this->execute($requestParam);
        if ($responseParam['code']!=Normal::SUC){
            return $responseParam;
        }
        $skuNos= array_column($responseParam['data']['result']['SkuList'],'SkuNo');
        //库存
        $stockList=$this->queryStockSynchro($skuNos);
        //组装数据
        foreach ($responseParam['data']['result']['SkuList'] as &$v){
            $v['stock']=$stockList['data'][$v['SkuNo']]??0;
            unset($v);
        }
        return $responseParam;
    }

    /**
     * 根据SkuNo获取商品列表
     */
    public function queryGoodsListBySkuNo($param=[])
    {
        $data = [
            "SkuReqs"    => $param['skuNos'],
        ];
        $requestParam = [
            'method'    => 'SkuSynchro',
            'data'      => $data,
        ];
        $responseParam=$this->execute($requestParam);
        if ($responseParam['code']!=Normal::SUC){
            return $responseParam;
        }
        //库存
        $stockList=$this->queryStockSynchro($param['skuNos']);
        //组装数据
        foreach ($responseParam['data'] as &$v){
            $v['stock']=$stockList['data'][$v['SkuNo']]??0;
            unset($v);
        }
        return $responseParam;
        
    }

    /**
     * 获取商品库存
     */
    public function queryStockSynchro($skuNos)
    {
        //创建订单数据
        $data = [
            "StockReqs" => $skuNos,
        ];
        $requestParam = [
            'method'    => 'StockSynchro',
            'data'      => $data,
        ];
        $stockListRes=$this->execute($requestParam);
        if ($stockListRes['code']!=Normal::SUC){
            return Normal::returnCode(Normal::SUC,'获取库存成功',[]);
        }
        return Normal::returnCode(Normal::SUC,'获取库存成功',array_column($stockListRes['data'],'Quantity','SkuNo'));
    }

    /**
     * 获取发货物流信息
     */
    public function orderExpress( $param = [] )
    {
        if( empty($param['OrderNosReqs']) ) {
            return Normal::returnCode(Normal::FAIL,"except param OrderNosReqs");
        }
        $data = [
            "OrderNosReqs"  => [$param['supplier_dsn']],
        ];
        $requestParam = [
            'method'    => 'PostSynchro',
            'data'      => $data,
        ];
        return $this->execute($requestParam);
    }

    /**
     * 获取sign参数
     */
    private function getSign( $param = [] )
    {
        $date = date("Y-m-d");
        $str = $this->clientConfig['key'].$date.$param['interfacename'].$param['content'];
        return md5($str);
    }


    /**
     * CURL请求
     * @param $params
     * @return mixed
     */
    public function execute( $param = [] )
    {
        $method = $param['method'];
        $data  = [
            'interfacename'     => $method,
            'parenter'          => $this->clientConfig['partner'],
            'content'           => json_encode($param['data'])
        ];
        $token   = $this->getSign($data);
        $data           = $param['data'];
        $url            = $this->clientConfig['baseurl'].$this->clientConfig[$method];
        $parameter = [
            [
                'tag'       => 'Shopweini_'.$method,
                'uid'       => IdService::instance()->getOtherID(),
                'url'       => $url,
                'data'      => $data,
                'method'    => 'post',
                'format'    => 'json',
                'header'    => [
                    "Content-Type: application/json",
                    "Accept:application/json",
                    "interfacename:{$method}",
                    "parenter:{$this->clientConfig['partner']}",
                    "token:{$token}"
                ],
            ],
        ];
        if( in_array($param['method'],['SkuListSynchro','StockSynchro','SkuSynchro']) ) {
            $resTask = TaskWorker::instance()->addTask($parameter,'handleDiableTask');
        } else {
            $resTask = TaskWorker::instance()->addTask($parameter);
        }
        $resTask = current($resTask);
        $resHttp = json_decode($resTask['response']['result'], true);
        if( in_array($method,['AddOrderAsync']) ) {
            if( isset($resHttp['success']) && $resHttp['success'] == true && $resHttp['Code'] == '0000' ) {
                return Normal::returnCode(Normal::SUC,"操作成功",$resHttp);
            }
            $errorMsg = $resHttp['Message']??'请求失败';
        } else if ( in_array($method,['SkuListSynchro','OrderCancel','LogisticsSynchro']) ) {
            if( isset($resHttp['validate']) && $resHttp['validate'] == true ) {
                return Normal::returnCode(Normal::SUC,"操作成功",$resHttp);
            }
            $errorMsg = $resHttp['message']??'请求失败';
        } else if( in_array($method,['PostSynchro']) ) {
            if( isset($resHttp['Message']) ) {
                return Normal::returnCode(Normal::FAIL,$resHttp['Message']);
            }
            $currentExpress = current($resHttp);
            if( empty($currentExpress['OrderNo']) ) {
                return Normal::returnCode(Normal::FAIL,"未发货",$resHttp);
            }
            return Normal::returnCode(Normal::SUC,"操作成功",$resHttp);
        }else if( in_array($method,['StockSynchro','SkuSynchro'])){
            return Normal::returnCode(Normal::SUC,"操作成功",$resHttp);
        }
        return Normal::returnCode(Normal::FAIL,$errorMsg);
    }

    /**
     * 获取发货物流信息
     */
    public function queryOrderExpress( $param = [] )
    {
        $data = [
            "OrderNosReqs"  => [$param['supplier_dsn']],
        ];
        $requestParam = [
            'method'    => 'PostSynchro',
            'data'      => $data,
        ];
        return $this->execute($requestParam);
    }
}
